package com.shareware.common.secure.hash

import com.shareware.common.utils.log
import com.shareware.common.utils.toHexString
import java.io.File
import java.io.FileInputStream
import java.security.MessageDigest
import javax.crypto.Mac
import javax.crypto.spec.SecretKeySpec

/**
 * desc: 功能描述
 * email: mobiledeveloper@qq.com
 */
class SHA256 private constructor() {

    companion object {
        //recommend "SHA-256", "SHA-384", "SHA-512"
        private const val ALGORITHM_NAME = "SHA-256"
        private const val ALGORITHM_MAC_NAME = "HmacSHA256"
        private const val TAG = "SHA256"

        fun sha256Encrypt(content: String): String {
            return if (content.isEmpty()) {
                log(TAG, "content is not null")
                ""
            } else {
                try {
                    val messageDigest = MessageDigest.getInstance(ALGORITHM_NAME)
                    messageDigest.update(content.toByteArray())
                    messageDigest.digest().toHexString()
                } catch (ignore: Exception) {
                    log(TAG, "SHA error")
                    ""
                }
            }
        }

        fun sha256FileEncrypt(file: File): String {
            return if (file.exists() && file.length() > 0) {
                try {
                    var encrypt = ""
                    val messageDigest = MessageDigest.getInstance(ALGORITHM_NAME)
                    FileInputStream(file).use {
                        val bytes = ByteArray(8192)
                        var length: Int
                        var isEncrypt = false
                        while (it.read(bytes).also { len ->
                                    length = len
                                } > 0) {
                            messageDigest.update(bytes, 0, length)
                            isEncrypt = true
                        }
                        if (isEncrypt) {
                            encrypt = messageDigest.digest().toHexString()
                        }
                    }
                    encrypt
                } catch (ignore: Exception) {
                    log(TAG, "${ignore.message}")
                    ""
                }
            } else {
                log(TAG, "file is invalid")
                ""
            }
        }

        fun sha256HMac(content: String, key: String): String {
            return if (content.isEmpty() || key.isEmpty()) {
                log(TAG, "param error")
                ""
            } else {
                try {
                    val sha256Mac = Mac.getInstance(ALGORITHM_MAC_NAME)
                    val secretKey = SecretKeySpec(key.toByteArray(), ALGORITHM_MAC_NAME)
                    sha256Mac.init(secretKey)
                    val doFinal = sha256Mac.doFinal(content.toByteArray())
                    doFinal.toHexString()
                } catch (ignore: Exception) {
                    log(TAG, "sha256HMac error")
                    ""
                }
            }
        }
    }
}